<!DOCTYPE html>
<html>
<head>
    <title>unimall API文档 方法详情</title>
    <link href="https://iotechn.oss-cn-hangzhou.aliyuncs.com/open/style/commons.css" rel="stylesheet" type="text/css"/>
    <link rel="stylesheet" href="https://iotechn.oss-cn-hangzhou.aliyuncs.com/open/stylesheets/commons.css">
    <link rel="stylesheet" type="text/css" href="https://iotechn.oss-cn-hangzhou.aliyuncs.com/open/stylesheets/index-news.css">
    <script src="https://iotechn.oss-cn-hangzhou.aliyuncs.com/open/js/jquery-lastest.js"></script>
</head><body>
<div class="open-header clearfix">
    <div class="pm">
        <div class="open-header-c1 fl">
            <!-- logo -->
            <a href="/"><span class='open-header-icon '></span></a>
        </div>
    </div>
</div>
<div class="open-nav">
    <div class="pm">
        <ul class="openapi-nav">
            <li class="openapi-nav-apis" type=""><a href="/info/group/${gp}">API</a></li>
        </ul>
    </div>
</div>
<script type="text/javascript">
    function setLang(lang){
        $.post("/lang",{lang:lang},function(result){
            window.location.reload(true);
        });
    }
    var selected="index";
    var locationPath=window.location.pathname.toLowerCase();
    if(locationPath.indexOf("apis")>0||locationPath.indexOf("testapi")>0){
        selected="apis";
    }else if(locationPath.indexOf("docs")>0){
        selected="docs";
    }else if(locationPath.indexOf("enter")>0){
        selected="enter";
    }
    $(".openapi-nav li").removeClass("active");
    $(".openapi-nav-"+selected).addClass("active");
</script>  <div class="pm">
    <nav class="open-breadcrumbs">
        <a href="#" >API</a>/<a href="/info/group/${gp}">${gp}</a>/${model.name}
    </nav>
    <div class="clearfix">
        <div class="open-grid-c1">
            <aside class="open-sideber">
                <ul class="open-sideber-list1">
                    <li>
                        <a href="javascript:void(0);" onclick="return false;" class="groupName ">${gp}开放接口</a>
                        <ul class="open-sideber-list2">
                            <#list methods as method>
                                <li data-name="${method.name}">
                                    <a href="/info/api/${gp}/${method.name}">
                                            ${method.description}
                                        <br>${gp}.${method.name}
                                    </a>
                                </li>
                             </#list>
                        </ul>
                    </li>
                </ul>
            </aside>
        </div>
        <div class="open-grid-c2">
            <section class="open-detail">
                <h1>${model.name}</h1>
                <section>
                    <h2>API 描述</h2>
                    <p>${model.description}:${model.detail}</p>
                </section>
                <section>
                    <h2>参数列表</h2>
                    <section>
                        <h3>系统级别参数</h3>
                        <table>
                            <thead>
                            <tr>
                                <th>必要性</th>
                                <th>参数名</th>
                                <th>类型</th>
                                <th>描述</th>
                            </tr>
                            </thead>
                            <tbody>
                            <tr>
                                <td>必填</td>
                                <td>_gp</td>
                                <td><a href="javascript:void(0);">string</a></td>
                                <td>method,所在分组 ${gp}</td>
                            </tr>

                            <tr>
                                <td>必填</td>
                                <td>_mt</td>
                                <td><a href="javascript:void(0);">string</a></td>
                                <td>method,请求的方法名 ${model.name}</td>
                            </tr>
                            <tr>
                                <td>必填</td>
                                <td>timestamp</td>
                                <td><a href="javascript:void(0);">string</a></td>
                                <td>请求时间戳，精确到毫秒位</td>
                            </tr>
                            <tr>
                                <td>必填</td>
                                <td>appId</td>
                                <td><a href="javascript:void(0);">string</a></td>
                                <td>向开放平台申请的appId</td>
                            </tr>
                            <tr>
                                <td>必填</td>
                                <td>sign</td>
                                <td><a href="javascript:void(0);">string</a></td>
                                <td>使用AppSecret对参数的签名</td>
                            </tr>
                            </tbody>
                        </table>
                        <hr>
                        <h3>应用级别参数</h3>
                        <table>
                            <thead>
                            <tr>
                                <th>必要性</th>
                                <th>参数名</th>
                                <th>class类型</th>
                                <th>方式类型</th>
                                <th>描述</th>
                            </tr>
                            </thead>
                            <tbody>
                            <#list model.parameters as param>
                                <tr>
                                    <td>
                                        <#if param.required>
                                            必填
                                        <#else>
                                            可空
                                        </#if>
                                    </td>
                                    <td>${param.name}</td>
                                    <td>${param.paramType}</td>
                                    <td>${param.type}</td>
                                    <td>${param.description}</td>
                                </tr>
                            </#list>

                            </tbody>
                        </table>
                    </section>
                </section>
                <section>
                    <h2>返回值</h2>
                    <section>
                        <h3>返回类型 </h3>
                        <p>${model.retType} </p>
                        <p>注:所有的DO对象都有Long id , Date gmtUpdate , Date gmtCreate 三个属性</p>

                        <#if model.retObj??>
                            <hr>
                            <h3>类型定义</h3>
                            <table>
                                <thead>
                                <tr>
                                    <th>属性名</th>
                                    <th>类型</th>
                                    <th>描述</th>
                                </tr>
                                </thead>
                                <tbody>
                                    <#list model.retObj as field>
                                        <tr>
                                            <td>${field.name}</td>
                                            <td>${field.type}</td>
                                            <td>暂无描述</td>
                                        </tr>
                                    </#list>
                                </tbody>
                            </table>
                        </#if>
                    </section>
                </section>
                <section>
                    <h2>测试Api</h2>
                    <table>
                        <thead>
                        <tr>
                            <th>parameter name</th>
                            <th>value</th>
                            <th>description</th>
                        </tr>
                        </thead>
                        <tbody>
                        <tr>
                            <td>_gp<span class="text-important">*</span></td>
                            <td id="_gp">${gp}</td>
                            <td>请求参数分组</td>
                        </tr>
                        <tr>
                            <td>_mt<span class="text-important">*</span></td>
                            <td id="_mt">${model.name}</td>
                            <td>请求参数名</td>
                        </tr>
                        <tr>
                            <td>timestamp<span class="text-important">*</span></td>
                            <td id="timestamp">timestamp</td>
                            <td>测试时 自动生成</td>
                        </tr>
                        <#list model.parameters as param>
                            <tr>
                                <td>${param.name}
                                    <#if param.required>
                                        <span class="text-important">*</span>
                                    </#if>
                                </td>
                                    <td><input id="${param.name}" name="${param.name}" type="text"></td>
                                    <td>${param.description}</td>
                            </tr>
                        </#list>
                        <tr>
                            <td>appId
                                <span class="text-important">*</span>
                            </td>
                            <td><input id="appId" name="appId" type="text"></td>
                            <td>AppId</td>
                        </tr>
                        <tr>
                            <td>appSecret
                                <span class="text-important">*</span>
                            </td>
                            <td><input id="appSecret" name="appSecret" type="text"></td>
                            <td>AppSecret</td>
                        </tr>
                        </tbody>
                    </table>
                    <hr>
                    <a href="javascript:" class="open-detail-btn" id="submitId">submit</a>
                    <hr>
                    <div class="clearfix">
                        <section style="margin-bottom: 20px">
                            <h2>request:</h2>
                            <pre class="prettyprint lang-http"><code id="urlParams" style="min-height: 100px" class="hljs"><span class="hljs-attribute"></span></code></pre>
                        </section>
                        <section style="margin-bottom: 20px">
                            <h2>response:</h2>
                            <pre class="prettyprint lang-json"><code id="result" style="min-height: 100px" class="hljs"></code></pre>
                        </section>
                    </div>
                </section>
                <section>
                    <h2>异常返回值</h2>
                    <section>
                        <table>
                            <thead>
                            <tr>
                                <th>异常返回值</th>
                                <th>描述</th>
                            </tr>
                            </thead>
                            <tbody>
                            <#list exceptionList as exc>
                            <tr>
                                <td>${exc.code}</td>
                                <td>${exc.msg}</td>
                            </tr>
                            </#list>

                            </tbody>
                        </table>
                    </section>
                </section>
            </section>
        </div>
    </div>
</div>

<div class="open-footer">
    <ul>
        <li><a href="#">API</a></li>
    </ul>
    <p>备案</p>
</div>
<script src="http://open.fengqu.com/js/md5.min.js"></script>
<script type="text/javascript">
    var path = location.pathname.split("/");
    var len = path.length;
    if(len > 2){
        var groupElement = $("." + path[len-2]);
        groupElement.addClass("active");
        groupElement.parent().parent().find("ul").css("display", "block");
        $("[data-name='" + decodeURI(path[len-1]) + "']").addClass("active");
    }
    $(".groupName").click(function(){
        if($(this).parent().parent().find("ul").css("display") == "block"){
            $(this).removeClass('active');
            $($(this).parent().parent().find("ul")).css("display", "none");
        }
        else{
            $(this).addClass('active');
            $($(this).parent().parent().find("ul")).css("display", "block");
        }
    });
    function setLang(lang){
        $.post("/lang",{lang:lang},function(result){
            window.location.reload(true);
        });
    }
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.2.0/highlight.min.js"></script>
<script>
    function getParamData(){
        //获取参数
        var requestData = {};
        requestData._gp = $("#_gp").text();
        requestData._mt = $("#_mt").text();
        <#list model.parameters as param>
        <#if param.type != "USER_ID">
        requestData.${param.name} = $("#${param.name}").val();
        </#if>
        </#list>
        return requestData;
    }

    $('#submitId').click(function(){
        var data = getParamData();
        data.timestamp = new Date().getTime()
        var appId = $("#appId").val();
        data.appId = appId
        var appSecret = $("#appSecret").val();
        // 使用JS实现签名算法
        var array = []
        for (var key in data) {
            array.push(data[key])
        }
        // 额外为签名加上 appSecert
        array.push(appSecret)
        var soredArray = encodeURI(array.sort().join(""))
        var sign = sha256_digest(soredArray)
        data.sign = sign
        $.ajax({
            type:"POST",
            url:'/m.api',
            dataType: "json",
            data: data,
            beforeSend: function (request) {
            },
            cache:true,
            success:success,
            error:error
        });


        function success(data){
            $("#result").text(JSON.stringify(data, undefined, 4));
        }

        function error(data){
            console.log(data);
        }

        var urlValue = [];
        for(var prop in data){
            urlValue.push(prop + "=" + data[prop]);
        }
        $("#urlParams").text("POST \r\n--url "+"/m.api\r\n--data:" + urlValue.join("&"));
    });


    /** sha256 加密算法 **/

    function rotateRight(n,x) {
        return ((x >>> n) | (x << (32 - n)));
    }
    function choice(x,y,z) {
        return ((x & y) ^ (~x & z));
    }
    function majority(x,y,z) {
        return ((x & y) ^ (x & z) ^ (y & z));
    }
    function sha256_Sigma0(x) {
        return (rotateRight(2, x) ^ rotateRight(13, x) ^ rotateRight(22, x));
    }
    function sha256_Sigma1(x) {
        return (rotateRight(6, x) ^ rotateRight(11, x) ^ rotateRight(25, x));
    }
    function sha256_sigma0(x) {
        return (rotateRight(7, x) ^ rotateRight(18, x) ^ (x >>> 3));
    }
    function sha256_sigma1(x) {
        return (rotateRight(17, x) ^ rotateRight(19, x) ^ (x >>> 10));
    }
    function sha256_expand(W, j) {
        return (W[j&0x0f] += sha256_sigma1(W[(j+14)&0x0f]) + W[(j+9)&0x0f] +
            sha256_sigma0(W[(j+1)&0x0f]));
    }

    /* Hash constant words K: */
    var K256 = new Array(
        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
        0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
        0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
        0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
        0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
        0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
        0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
        0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
        0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
        0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
        0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
        0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
        0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
        0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
        0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
        0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
    );

    /* global arrays */
    var ihash, count, buffer;
    var sha256_hex_digits = "0123456789abcdef";

    /* Add 32-bit integers with 16-bit operations (bug in some JS-interpreters:
    overflow) */
    function safe_add(x, y)
    {
        var lsw = (x & 0xffff) + (y & 0xffff);
        var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
        return (msw << 16) | (lsw & 0xffff);
    }

    /* Initialise the SHA256 computation */
    function sha256_init() {
        ihash = new Array(8);
        count = new Array(2);
        buffer = new Array(64);
        count[0] = count[1] = 0;
        ihash[0] = 0x6a09e667;
        ihash[1] = 0xbb67ae85;
        ihash[2] = 0x3c6ef372;
        ihash[3] = 0xa54ff53a;
        ihash[4] = 0x510e527f;
        ihash[5] = 0x9b05688c;
        ihash[6] = 0x1f83d9ab;
        ihash[7] = 0x5be0cd19;
    }

    /* Transform a 512-bit message block */
    function sha256_transform() {
        var a, b, c, d, e, f, g, h, T1, T2;
        var W = new Array(16);

        /* Initialize registers with the previous intermediate value */
        a = ihash[0];
        b = ihash[1];
        c = ihash[2];
        d = ihash[3];
        e = ihash[4];
        f = ihash[5];
        g = ihash[6];
        h = ihash[7];

        /* make 32-bit words */
        for(var i=0; i<16; i++)
            W[i] = ((buffer[(i<<2)+3]) | (buffer[(i<<2)+2] << 8) | (buffer[(i<<2)+1]
                << 16) | (buffer[i<<2] << 24));

        for(var j=0; j<64; j++) {
            T1 = h + sha256_Sigma1(e) + choice(e, f, g) + K256[j];
            if(j < 16) T1 += W[j];
            else T1 += sha256_expand(W, j);
            T2 = sha256_Sigma0(a) + majority(a, b, c);
            h = g;
            g = f;
            f = e;
            e = safe_add(d, T1);
            d = c;
            c = b;
            b = a;
            a = safe_add(T1, T2);
        }

        /* Compute the current intermediate hash value */
        ihash[0] += a;
        ihash[1] += b;
        ihash[2] += c;
        ihash[3] += d;
        ihash[4] += e;
        ihash[5] += f;
        ihash[6] += g;
        ihash[7] += h;
    }

    /* Read the next chunk of data and update the SHA256 computation */
    function sha256_update(data, inputLen) {
        var i, index, curpos = 0;
        /* Compute number of bytes mod 64 */
        index = ((count[0] >> 3) & 0x3f);
        var remainder = (inputLen & 0x3f);

        /* Update number of bits */
        if ((count[0] += (inputLen << 3)) < (inputLen << 3)) count[1]++;
        count[1] += (inputLen >> 29);

        /* Transform as many times as possible */
        for(i=0; i+63<inputLen; i+=64) {
            for(var j=index; j<64; j++)
                buffer[j] = data.charCodeAt(curpos++);
            sha256_transform();
            index = 0;
        }

        /* Buffer remaining input */
        for(var j=0; j<remainder; j++)
            buffer[j] = data.charCodeAt(curpos++);
    }

    /* Finish the computation by operations such as padding */
    function sha256_final() {
        var index = ((count[0] >> 3) & 0x3f);
        buffer[index++] = 0x80;
        if(index <= 56) {
            for(var i=index; i<56; i++)
                buffer[i] = 0;
        } else {
            for(var i=index; i<64; i++)
                buffer[i] = 0;
            sha256_transform();
            for(var i=0; i<56; i++)
                buffer[i] = 0;
        }
        buffer[56] = (count[1] >>> 24) & 0xff;
        buffer[57] = (count[1] >>> 16) & 0xff;
        buffer[58] = (count[1] >>> 8) & 0xff;
        buffer[59] = count[1] & 0xff;
        buffer[60] = (count[0] >>> 24) & 0xff;
        buffer[61] = (count[0] >>> 16) & 0xff;
        buffer[62] = (count[0] >>> 8) & 0xff;
        buffer[63] = count[0] & 0xff;
        sha256_transform();
    }

    /* Split the internal hash values into an array of bytes */
    function sha256_encode_bytes() {
        var j=0;
        var output = new Array(32);
        for(var i=0; i<8; i++) {
            output[j++] = ((ihash[i] >>> 24) & 0xff);
            output[j++] = ((ihash[i] >>> 16) & 0xff);
            output[j++] = ((ihash[i] >>> 8) & 0xff);
            output[j++] = (ihash[i] & 0xff);
        }
        return output;
    }

    /* Get the internal hash as a hex string */
    function sha256_encode_hex() {
        var output = new String();
        for(var i=0; i<8; i++) {
            for(var j=28; j>=0; j-=4)
                output += sha256_hex_digits.charAt((ihash[i] >>> j) & 0x0f);
        }
        return output;
    }

    /* Main function: returns a hex string representing the SHA256 value of the
    given data */
    function sha256_digest(data) {
        sha256_init();
        sha256_update(data, data.length);
        sha256_final();
        return sha256_encode_hex();
    }
</script>

</body>
</html>
